﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Subjects;
using System.Windows;
using System.Windows.Input;
using Rxx.Labs.Properties;

namespace Rxx.Labs.Reactive.UI
{
	[DisplayName("Observable Commands (Updated)")]
	[Description("Binding and subscribing to commands.")]
	public partial class CommandLab : BaseLab
	{
		public ICommand ToggleOptionsCommand
		{
			get
			{
				return toggleOptionsCommand;
			}
		}

		public ICommand SayHelloCommand
		{
			get
			{
				return sayHelloCommand;
			}
		}

		public bool AreCommandsEnabled
		{
			get
			{
				return sayHelloCommand.CanExecute(null);
			}
			set
			{
				sayHelloCommand.OnNext(value);
			}
		}

		private readonly CommandSubject sayHelloCommand = new CommandSubject();
		private readonly AnonymousCommand toggleOptionsCommand;

		public CommandLab()
		{
			toggleOptionsCommand = new AnonymousCommand(
				canExecute: _ => AreCommandsEnabled,
				execute: _ => OptionsPanel.Visibility =
					OptionsPanel.Visibility == Visibility.Visible
					? Visibility.Collapsed
					: Visibility.Visible);

			InitializeComponent();
		}

		protected override IEnumerable<IDisposable> Main()
		{
			yield return sayHelloCommand.Subscribe(ConsoleOutput);

			yield return sayHelloCommand.CanExecuteObservable().Subscribe(
				_ => toggleOptionsCommand.RaiseCanExecuteChanged());

#if !SILVERLIGHT
			yield return ApplicationCommands.New.CanExecuteObservable()
				.Subscribe(canExecute => TraceLine(Text.CanExecuteChangedFormat, Text.New, canExecute));

			yield return ApplicationCommands.New.Subscribe(
				element: this,
				onExecuted: e => TraceLine(Text.New),
				onCanExecute: e => e.EventArgs.CanExecute = AreCommandsEnabled);
#endif
		}
	}
}